<template>
  <a-modal
    v-model:open="visible"
    :mask-closable="false"
    width="60%"
    title="多规格"
    :style="{ top: '20px' }"
  >
    {{ formData.propertyIds }}
    <a-form :model="formData" ref="formRef">
      <a-row>
        <a-col :span="24">
          <a-form-item label="规格">
            <a-input-group compact>
              <a-select
                style="width: 300px"
                :value="formData.propertyIds"
                mode="multiple"
                placeholder="请选择属性"
                :loading="loading"
                :disabled="loading"
                @change="propertyIdsChange"
              >
                <a-select-option v-for="item in propertyData" :key="item.id" :value="item.id">
                  {{ item.name }}
                </a-select-option>
              </a-select>
              <a-button
                :disabled="formData.propertyIds.length === 0"
                type="primary"
                @click="generateSpec"
              >
                生成规格
              </a-button>
            </a-input-group>
          </a-form-item>
        </a-col>
        <a-col :span="24" style="padding-top: 10px" v-if="formData.propertyIds.length > 0">
          <div v-loading="loading">
            <vxe-grid
              ref="grid"
              resizable
              show-overflow
              highlight-hover-row
              keep-source
              row-id="id"
              height="500"
              :data="formData.productData"
              :columns="tableColumn"
              :toolbar-config="toolbarConfig"
            >
              <!-- 工具栏 -->
              <template #toolbar_buttons>
                <a-space>
                  <a-button type="primary" @click="addRow()">新增</a-button>
                </a-space>
              </template>

              <template #propertyValue_default="{ column, rowIndex, row }">
                <a-form-item
                  :name="['productData', rowIndex, column.field]"
                  :rules="[{ required: true, message: '请选择属性值' }]"
                  no-style
                >
                  <a-select
                    :value="row[column.field]"
                    :placeholder="`请选择${column.title}`"
                    @change="(value) => propertyValueChange(column, row, value)"
                    allow-clear
                  >
                    <a-select-option
                      v-for="item in propertyData.find((p) => p.id === column.field)?.items || []"
                      :key="item.id"
                      :value="item.id"
                    >
                      {{ item.name }}
                    </a-select-option>
                  </a-select>
                </a-form-item>
              </template>
              <template #unit_default="{ column, rowIndex, row }">
                <a-form-item
                  :name="['productData', rowIndex, column.field]"
                  :rules="[{ required: true, message: '请选择单位' }]"
                  no-style
                >
                  <unit-selector v-model:value="row[column.field]" />
                </a-form-item>
              </template>
              <template #price_default="{ column, rowIndex, row }">
                <a-form-item
                  :name="['productData', rowIndex, column.field]"
                  :rules="[{ required: true, message: '请输入价格' }]"
                  no-style
                >
                  <a-input-number v-model:value="row[column.field]" min="0" />
                </a-form-item>
              </template>
              <template #action_default="{ rowIndex }">
                <a-space>
                  <a-button danger @click="delRow(rowIndex)">删除</a-button>
                </a-space>
              </template>
            </vxe-grid>
          </div>
        </a-col>
      </a-row>
    </a-form>
    <template #footer>
      <div class="form-modal-footer" v-permission="['base-data:product:spec:add']">
        <a-space>
          <a-button type="primary" :loading="loading" html-type="submit" @click="submit">
            保存
          </a-button>
          <a-button :loading="loading" @click="closeDialog">取消</a-button>
        </a-space>
      </div>
    </template>
  </a-modal>
</template>

<script setup>
  import { getCurrentInstance, ref } from 'vue';
  import * as propertyApi from '@/api/base-data/product/property';
  import * as productApi from '@/api/base-data/product/info';
  import UnitSelector from '@/components/Selector/src/UnitSelector.vue';
  import { getCartesian } from '@/utils/cartesian';

  // this对象
  const instance = getCurrentInstance();

  const emit = defineEmits(['confirm', 'close']);

  const visible = ref(false);

  // 加载中
  const loading = ref(false);

  // 表单引用
  const formRef = ref();

  const props = defineProps({
    productId: {
      type: String,
      required: true,
    },
  });

  // 商品数据
  const productInfo = ref({});

  // 属性数据
  const propertyData = ref([]);

  // 表单数据
  const formData = ref({
    propertyIds: [],
    productData: [],
  });

  // 初始化表单数据
  const initFormData = () => {
    formData.value.propertyIds = [];
    formData.value.productData = [];
  };

  // 加载数据
  const loadData = () => {
    loading.value = true;
    productApi
      .get(props.productId)
      .then((data) => {
        productInfo.value = data;
        propertyApi
          .getModelorByCategory(data.categoryId)
          .then((res) => {
            propertyData.value = res;
          })
          .finally(() => {
            loading.value = false;
          });
      })
      .finally(() => {
        loading.value = false;
      });
  };

  // 表格列
  const tableColumn = ref([]);

  // 默认列
  const defaultColumn = ref([
    {
      title: '库存单位',
      field: 'stockUnit',
      width: 120,
      slots: { default: 'unit_default' },
    },
    {
      title: '采购价（元）',
      field: 'purchasePrice',
      width: 120,
      slots: { default: 'price_default' },
    },
    {
      title: '零售单位',
      field: 'retailUnit',
      width: 120,
      slots: { default: 'unit_default' },
    },
    {
      title: '零售价（元）',
      field: 'retailPrice',
      width: 120,
      slots: { default: 'price_default' },
    },
    {
      title: '销售单位',
      field: 'salesUnit',
      width: 120,
      slots: { default: 'unit_default' },
    },
    {
      title: '销售价（元）',
      field: 'salePrice',
      width: 120,
      slots: { default: 'price_default' },
    },
    { title: '操作', width: 80, fixed: 'right', slots: { default: 'action_default' } },
  ]);

  // 工具栏配置
  const toolbarConfig = ref({
    // 缩放
    zoom: false,
    // 自定义表头
    custom: false,
    // 右侧是否显示刷新按钮
    refresh: false,
    // 自定义左侧工具栏
    slots: {
      buttons: 'toolbar_buttons',
    },
  });

  // 属性选择改变
  const propertyIdsChange = (value) => {
    value?.sort((a, b) => a - b);
    formData.value.propertyIds = value;
    tableColumn.value = [];
    value.forEach((item) => {
      tableColumn.value.push({
        title: propertyData.value.find((p) => p.id === item)?.name,
        field: `${item}`,
        minWidth: 120,
        slots: { default: 'propertyValue_default' },
      });
    });
    tableColumn.value.push(...defaultColumn.value);
  };

  // 属性值选择改变
  const propertyValueChange = (column, row, value) => {
    row[column.field] = value;
    if (value) {
      const validPropertyValues = calculatePropertyValues(row);
      if (
        formData.value.productData.filter(
          (item) => item.validPropertyValues === validPropertyValues,
        ).length > 0
      ) {
        row[column.field] = null;
        _This().$msg.createError('已存在相同规格');
        return;
      }
      row.validPropertyValues = validPropertyValues;
    }
  };

  // 生成规格
  const generateSpec = () => {
    loading.value = true;
    new Promise((resolve) => {
      let sets = [];
      formData.value.propertyIds.forEach((item) => {
        sets.push(propertyData.value.find((p) => p.id === item)?.items.map((item) => item.id));
      });
      resolve(sets);
    })
      .then((res) => {
        getCartesian(res).forEach((item) => {
          addRow(
            item.reduce(
              (acc, cur, index) => ({ ...acc, [`${formData.value.propertyIds[index]}`]: cur }),
              {},
            ),
          );
        });
      })
      .finally(() => {
        loading.value = false;
      });
  };

  // 添加行
  const addRow = (propertyValues) => {
    let validPropertyValues;
    if (propertyValues) {
      validPropertyValues = calculatePropertyValues(propertyValues);
      if (
        formData.value.productData.filter(
          (item) => item.validPropertyValues === validPropertyValues,
        ).length > 0
      ) {
        return;
      }
    }
    formData.value.productData.push({
      stockUnit: productInfo.value.stockUnit,
      purchasePrice: productInfo.value.purchasePrice,
      retailUnit: productInfo.value.retailUnit,
      retailPrice: productInfo.value.retailPrice,
      salesUnit: productInfo.value.salesUnit,
      salePrice: productInfo.value.salePrice,
      ...propertyValues,
      validPropertyValues: validPropertyValues,
    });
  };

  // 删除行
  const delRow = (rowIndex) => {
    formData.value.productData.splice(rowIndex, 1);
  };

  // 计算PropertyValues
  const calculatePropertyValues = (propertyValues) => {
    if (propertyValues) {
      return Object.keys(propertyValues)
        .filter((key) => formData.value.propertyIds.includes(key))
        .map(
          (key) =>
            (propertyValues[key] = propertyData.value
              .find((p) => p.id === key)
              ?.items.find((item) => item.id === propertyValues[key])?.id),
        )
        .filter((item) => item !== undefined)
        .join(',');
    }
  };

  // 提交表单事件
  const submit = () => {
    formRef.value.validate().then((valid) => {
      if (valid) {
        formData.value.productData.forEach((item) => {
          item.propertys = formData.value.propertyIds.map((id) => {
            return {
              propertyId: id,
              propertyValueId: item[id],
            };
          });
        });
        console.log(JSON.stringify(formData.value.productData));
      }
    });
  };

  // 打开弹窗
  const openDialog = () => {
    visible.value = true;
    initFormData();
    loadData();
  };

  // 关闭对话框
  const closeDialog = () => {
    visible.value = false;
    emit('close');
  };

  // 组件实例对象
  const _This = () => {
    return instance.appContext.config.globalProperties;
  };

  defineExpose({
    openDialog,
  });
</script>

<style scoped></style>
